﻿using shenghua.Basics;
using shenghua.Basics.MemberLevels;
using shenghua.Commodity.Commodities;
using shenghua.Common.CustomValueType;
using shenghua.Member.XP.Median;
using shenghua.Member.Coupons;
using shenghua.Marketing.SalesPromotions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Abp.UI;

namespace shenghua.Order.Orders.Median
{
    /// <summary>
    /// 订单商品集合，可以计算各种优惠，得到最终价格
    /// </summary>
    public class CommodityCollection
    {
        private SettingManager _settingManager;
        public List<CommodityCollectionItem> Items { get; private set; }
        public MemberCoupon Coupon { get; private set; }
        public Member.Members.Member Member { get; set; }

        public bool HasCoupon
        {
            get
            {
                return Coupon != null;
            }
        }
        public string CouponName
        {
            get
            {
                return HasCoupon ? Coupon.Name : null;
            }
        }
        public Money CouponAmount
        {
            get
            {
                return  Coupon == null ? new Money() : Coupon.Amount;
            }
        }
        public int? CouponId
        {
            get
            {
                return HasCoupon ? (int?)Coupon.Id : null;
            }
        }
        public string CouponProfile
        {
            get
            {
                return HasCoupon ? Coupon.Profile : "";
            }
        }
        public int UsedXPValue { get; private set; }
        public Money XPAmount { get; private set; }
        /// <summary>
        /// 奖励的积分，这个需要通过具体的设置才可以计算
        /// </summary>
        public int BounsXPValue
        {
            get
            {
                if (!_settingManager.GetCanGainXPFromConsumption()) return 0;
                if (_settingManager.GetIsXPGainedByOrderTotalAmount())
                {
                    // 根据总价计算
                    int rate = _settingManager.GetXPGainedByOneAmount();
                    return (int)(TotalAmount.Value * rate);
                }
                else
                {
                    // 根据产品单独计算
                    int totalXPValue = 0;
                    foreach(var item in Items)
                    {
                        totalXPValue += item.XPValue * item.Count;
                    }
                    return totalXPValue;
                }
            }
        }
        public Money SumedTotalAmount
        {
            get
            {
                Money totalAmount = new Money();
                foreach (var item in Items)
                {
                    totalAmount += item.Price * item.Count;
                }
                return totalAmount;
            }
        }
        public Money TotalAmount
        {
            get
            {
                return SumedTotalAmount - CouponAmount - XPAmount;
            }
        }
        public int TotalCount
        {
            get
            {
                int totalCount = 0;
                foreach(var item in Items)
                {
                    totalCount += item.Count;
                }
                return totalCount;
            }
        }

        public CommodityCollection(
            List<CommodityCollectionItem> items,
            Member.Members.Member member,
            SettingManager settingManager)
        {
            Init(items, null, 0, member, settingManager);
        }

        public CommodityCollection(
            List<CommodityCollectionItem> items,
            MemberCoupon coupon,
            int xpValue,
            Member.Members.Member member,
            SettingManager settingManager)
        {
            Init( items, coupon, xpValue, member, settingManager);
        }
        
        private void Init(
            List<CommodityCollectionItem> items,
            MemberCoupon coupon,
            int xpValue,
            Member.Members.Member member,
            SettingManager settingManager)
        {
            Items = items;
            Coupon = coupon;
            UsedXPValue = xpValue;
            Member = member;
            _settingManager = settingManager;

            if (coupon != null)
            {
                if ( coupon.MemberId != member.Id )
                {
                    throw new UserFriendlyException("正在使用不属于用户的优惠券");
                }
                if (!coupon.CanUse(items))
                {
                    throw new UserFriendlyException("优惠券不满足使用条件");
                }
            }

            XPRule xpRule = GetXPRule();
            if(member.XPValue < xpRule.XPValue)
            {
                throw new Exception("用户积分值不足");
            }
            UsedXPValue = xpRule.XPValue;
            XPAmount = xpRule.XPAmount;
        }

        private XPRule GetXPRule()
        {
            if (!_settingManager.GetCanOffsetAmountByXP()) return new XPRule(new Money(0), 0);

            int tempXPValue = Math.Min(UsedXPValue, _settingManager.GetMaxXPOfOneOrder());
            int rate = _settingManager.GetXPNeededToOffsetOneAmount();
            Money tempAmountValue = new Money(tempXPValue / rate);
            Money maxAmount = SumedTotalAmount * _settingManager.GetMaxPercentOfOffsetAmount();

            if (tempAmountValue > maxAmount)
            {
                return new XPRule(maxAmount, (int)(maxAmount.Value * rate));
            }
            else
            {
                return new XPRule(tempAmountValue, tempXPValue);
            }
        }
    }

    public class CommodityCollectionItem
    {
        public int Count { get; private set; }
        public RealCommodity Commodity { get; private set; }

        public bool HasSalesPromotion
        {
            get
            {
                return Commodity.HasSalesPromotion;
            }
        }
        public string PromotionName
        {
            get
            {
                return Commodity.PromotionName;
            }
        }
        public Money PromotionPrice
        {
            get
            {
                return Commodity.PromotionPrice;
            }
        }
        public double Discount
        {
            get
            {
                return Commodity.Discount;
            }
        }

        public Money OriginalPrice
        {
            get
            {
                return Commodity.OriginalPrice;
            }
        }
        public Money DiscountPrice
        {
            get
            {
                return Commodity.DiscountPrice;
            }
        }
        public Money Price
        {
            get
            {
                return Commodity.Price;
            }
        }
        public Money TotalAmount
        {
            get
            {
                return Price * Count;
            }
        }


        public int CommodityId
        {
            get
            {
                return Commodity.CommodityId;
            }
        }
        public string CommodityName
        {
            get
            {
                return Commodity.CommodityName;
            }
        }
        public int? ShoppingOptionId
        {
            get
            {
                return Commodity.ShoppingOptionId;
            }
        }
        public bool Shelved
        {
            get
            {
                return Commodity.Shelved;
            }
        }
        public bool IsEnabledShoppingOption
        {
            get
            {
                return Commodity.IsEnabledShoppingOption;
            }
        }
        public bool IsForMember
        {
            get
            {
                return Commodity.IsForMember;
            }
        }
        public long MemberId
        {
            get
            {
                return Commodity.MemberId;
            }
        }
        public bool IsCollected
        {
            get
            {
                return Commodity.IsCollected;
            }
        }
        public int XPValue
        {
            get
            {
                return Commodity.XPValue;
            }
        }
        public int Inventory
        {
            get
            {
                return Commodity.Inventory;
            }
        }
        public int MinLimitCount
        {
            get
            {
                return Commodity.MinLimitCount;
            }
        }
        public int MaxLimitCount
        {
            get
            {
                return Commodity.MaxLimitCount;
            }
        }
        public string Picture
        {
            get
            {
                return Commodity.Picture;
            }
        }
        public Dictionary<string, string> ShoppingOptionParameters
        {
            get
            {
                return Commodity.ShoppingOptionParameters;
            }
        }

        public CommodityCollectionItem(int count, RealCommodity commodity)
        {
            Count = count;
            Commodity = commodity;
            
            if(!Commodity.IsValidCount(count))
            {
                if (count < MinLimitCount) Count = MinLimitCount;
                else if (count > MaxLimitCount) Count = MaxLimitCount;
                //throw new UserFriendlyException("商品数量应不小于起购量，不大于限购量");
            }
        }
    }
}
